package com.bihu.bihudemo.service.impl;

import com.bihu.bihudemo.entity.CommentLike;
import com.bihu.bihudemo.entity.Question;
import com.bihu.bihudemo.entity.dto.LikedCountDTO;
import com.bihu.bihudemo.entity.vo.QuestionVo;
import com.bihu.bihudemo.myenum.LikedStatusEnum;
import com.bihu.bihudemo.service.QuestionService;
import com.bihu.bihudemo.service.RedisService;
import com.bihu.bihudemo.utils.redis.RedisKeyUtils;
import com.bihu.bihudemo.utils.redis.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class RedisServiceImpl implements RedisService {
    @Autowired
    RedisTemplate redisTemplate;

    @Resource
    QuestionService questionService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public void saveLiked2Redis(String likedCommentId, String likedPostId) {
        //点赞
        String likedKey = RedisKeyUtils.getLikedKey(likedCommentId, likedPostId);
        redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED, likedKey, LikedStatusEnum.LIKE.getCode());
    }

    @Override
    public void unlikeFromRedis(String likedUserId, String likedPostId) {
        //取消赞
        String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
        redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED, key, LikedStatusEnum.UNLIKE.getCode());
    }

    @Override
    public void deleteLikedFromRedis(String likedUserId, String likedPostId) {
        //从redis中删除该条点赞记录
        String key = RedisKeyUtils.getLikedKey(likedUserId, likedPostId);
        redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
    }

    @Override
    public void incrementLikedCount(String likedCommentId) {
        //将评论的点赞总数+1
        redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedCommentId, 1);
    }

    @Override
    public void decrementLikedCount(String likedCommentId) {
        //将评论的点赞总数-1
        redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, likedCommentId, -1);
    }

    //从redis中拿到所有的点赞信息，方便做持久化操作
    @Override
    public List<CommentLike> getLikedDataFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE);
        List<CommentLike> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> entry = cursor.next();
            String key = (String) entry.getKey();
            //分离出 likedCommentId，likedUserID
            String[] split = key.split("::");
            String likedCommentId = split[0];
            String likedUserID = split[1];
            Integer value = (Integer) entry.getValue();
            //组装成 UserLike 对象
            CommentLike userLike = new CommentLike(Integer.parseInt(likedCommentId), Integer.parseInt(likedUserID), value);
            list.add(userLike);
            //记得持久化时清空缓存，不然数据库会爆炸
            redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
        }
        return list;
    }


    //从redis拿到对应平论的获赞总数，方便更新评论的点赞字段
    @Override
    public List<LikedCountDTO> getLikedCountFromRedis() {
        Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE);
        List<LikedCountDTO> list = new ArrayList<>();
        while (cursor.hasNext()) {
            Map.Entry<Object, Object> map = cursor.next();
            //将点赞数量存储在 LikedCountDT
            String key = (String) map.getKey();
            LikedCountDTO dto = new LikedCountDTO(Integer.parseInt(key), (Integer) map.getValue());
            list.add(dto);
            //从Redis中删除这条记录
            redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key);
        }
        return list;
    }


    /**
     * 增加文章阅读数量，先缓存起来
     *
     * @param question 文章
     */
    @Override
    public void addViewNum(QuestionVo question) {
        String key = "question:" + question.getId();

        Object viewCount = redisUtil.hGet(key, "viewCount");
        if (viewCount != null) {
            int count = Integer.parseInt(viewCount.toString());
            question.setReadNum(count + 1);
            redisUtil.hPut(key, "viewCount", String.valueOf(count + 1));
        } else {
            question.setReadNum(question.getReadNum() + 1);
            redisUtil.hPut(key, "viewCount", String.valueOf(question.getReadNum()));
        }
    }

    /**
     * 同步文章的阅读数到redis中
     */
    @Override
    public void SynViewNum() {
        ArrayList<Integer> idList = new ArrayList<>();
        //先检查缓存中有没有相关数据
        Set<String> keys = redisUtil.keys("question:*");
        //有就同步到数据库，同时删除key
        if (keys.size() != 0) {
            for (String keystr : keys) {
                int id = Integer.parseInt(keystr.substring("question:".length()));
                idList.add(id);
            }
            for (Integer id : idList) {
                Question question = questionService.getById(id);
                Integer count = Integer.parseInt(redisUtil.hGet("question:" + id, "viewCount").toString());
                question.setReadNum(count);
                questionService.updateById(question);
            }
            //删除keys
            redisUtil.delete(keys);
        } else {
            //没有就啥都不干
            System.out.println("记录阅读数的缓存为空，不用更新");
        }

    }


}


